[POWERPC][FIRMWARE] Firmware can now provide an RTAS stub
authorJimi Xenidis <jimix@watson.ibm.com>
Sun, 3 Jun 2007 14:39:31 +0000 (10:39 -0400)
committerJimi Xenidis <jimix@watson.ibm.com>
Sun, 3 Jun 2007 14:39:31 +0000 (10:39 -0400)
If the firmwares devtree contains a /rtas node, then firmware will
supply the interfaces that will allow a small RTAS stub to be
instantiated.  The RTAS stub is simply an hvcall that passes the RTAS
command block to the hypervisor.

Signed-off-by: Jimi Xenidis <jimix@watson.ibm.com>
xen/arch/powerpc/of_handler/Makefile
xen/arch/powerpc/of_handler/ofh.c
xen/arch/powerpc/of_handler/rtas.c [new file with mode: 0644]
xen/arch/powerpc/of_handler/vdevice.c
xen/arch/powerpc/of_handler/xen_hvcall.S
xen/arch/powerpc/powerpc64/hypercall_table.S

index 3b2dfdbe1091dd082ca536a82781da8d0c59eb60..1f3abfa2c1ebe6dc0122ba90455f1cad69d0ca72 100644 (file)
@@ -16,6 +16,7 @@ obj-y += leap.o
 obj-y += memory.o
 obj-y += ofh.o
 obj-y += papr.o
+obj-y += rtas.o
 obj-y += services.o
 obj-y += vdevice.o
 obj-y += xencomm.o
index 49febbb5e9b3460ba760956bdca8957a934252ff..84ea27fb4faef00f6376a28d8290047278b60da2 100644 (file)
@@ -234,6 +234,7 @@ ofh_init(ulong b)
 
     ofh_service_init(b);
     ofh_chosen_init(b);
+       ofh_rtas_init(b);
     ofh_options_init(b);
 }
 
diff --git a/xen/arch/powerpc/of_handler/rtas.c b/xen/arch/powerpc/of_handler/rtas.c
new file mode 100644 (file)
index 0000000..4343d3c
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright (C) IBM Corp. 2007
+ *
+ * Authors: Jimi Xenidis <jimix@watson.ibm.com>
+ */
+
+#include "ofh.h"
+#include <stdarg.h>
+#include <xen/lib.h>
+extern char _rtas_image_start[];
+extern char _rtas_image_end[];
+
+static int
+rtas_instantiate_rtas(u32 nargs, u32 nrets, s32 argp[], s32 retp[], ulong b)
+{
+    if (nargs == 1) {
+        if (nrets == 1) {
+            void *rtas_base_address = (void *)(ulong)argp[0];
+            u32 sz = (_rtas_image_end - _rtas_image_start);
+
+            memcpy(rtas_base_address,
+                   DRELA(&_rtas_image_start[0], b), sz);
+            retp[0] = (ulong)rtas_base_address;
+
+            return OF_SUCCESS;
+        }
+    }
+    return OF_FAILURE;
+}
+
+
+static struct ofh_methods _rtas_methods[] = {
+    { "instantiate-rtas", rtas_instantiate_rtas },
+    { NULL, NULL},
+};
+
+static struct ofh_ihandle _ih_rtas = {
+    .ofi_methods = _rtas_methods,
+};
+
+static int rtas_open(u32 b)
+{
+    u32 ih = DRELA((u32)&_ih_rtas, b);
+
+    return ih;
+}
+
+void ofh_rtas_init(ulong b)
+{
+    static const char path[] = "/rtas";
+    ofdn_t n;
+    void *m = ofd_mem(b);
+    u32 sz;
+
+    n = ofd_node_find(m, DRELA(&path[0], b));
+    if (n <= 0)
+        return;
+
+    sz = (_rtas_image_end - _rtas_image_start);
+    /* Round size up to a multiple of 0x1000 */
+    sz = ALIGN_UP(sz, PAGE_SIZE);
+
+    ofd_prop_add(m, n, DRELA((const char *)"rtas-size", b),
+                 &sz, sizeof(sz));
+
+    /* create an IO node */
+    ofd_io_create(m, n, (ulong)rtas_open);
+}
index 5ad5999cbfea4815a24966119d12797f76100200..8b710140726ae0acbc07acbc5cd71a4c4fc47d04 100644 (file)
@@ -36,7 +36,7 @@ ofh_vty_init(ofdn_t chosen, ulong b)
 
     /* find the vty */
     n = ofd_node_find(mem,
-                        DRELA((const char *)"/vdevice/vty", b));
+                      DRELA((const char *)"/vdevice/vty", b));
     if (n > 0) {
         /* PAPR VTERM */
         ret = ofd_getprop(mem, n, DRELA((const char *)"reg", b),
index 0182f83c7a7b5c999dce85a4dddf86ee539a1f7f..2d0a15acc97a728df9879e4fe9acbeaaf0e17448 100644 (file)
@@ -1,19 +1,21 @@
 /*
- * Copyright (C) 2005 Jimi Xenidis <jimix@watson.ibm.com>, IBM Corporation
- *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright (C) IBM Corp. 2005, 2007
+ *
+ * Authors: Jimi Xenidis <jimix@watson.ibm.com>
  */
 
 #include <asm/config.h>
 _GLOBAL(xen_hvcall)
     HSC
     blr
+
+/* The following stub will get instantiated as RTAS in the guest */    
+#define H_RTAS_PROXY 23
+    .p2align 3
+    .global _rtas_image_start
+    .global _rtas_image_end
+_rtas_image_start:
+    mr r4,r3
+    lis        r3,0xffff
+    ori        r3,r3,H_RTAS_PROXY
+    HSC
+    blr
+    nop
+_rtas_image_end:
index a54c838db0106f6d34c7b6832411728386c286a8..090b9592efc0e594fa51f81ef90b4779931d09ab 100644 (file)
@@ -27,7 +27,7 @@ __hypercall_table:
         .quad do_grant_table_op     /* 20 */
         .quad do_vm_assist
         .quad 0 /* do_update_va_mapping_otherdomain */
-        .quad 0 /* do_switch_vm86 */
+        .quad do_rtas_proxy /* do_switch_vm86 */
         .quad do_vcpu_op
         .quad do_ni_hypercall       /* 25 */
         .quad 0 /* do_mmuext_op */